#include "protobuf_parser.h"

#define PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, ret)\
    using namespace google::protobuf;\
    using namespace google::protobuf::compiler;\
    CHECKPTR_NULL_RETURN(msg, ret);\
    const DescriptorPool * descriptor_pool = importer_->pool();\
    CHECKPTR_NULL_RETURN(descriptor_pool, ret);\
    const Descriptor *desc_msg = descriptor_pool->FindMessageTypeByName(msg->GetTypeName());\
    CHECKPTR_NULL_RETURN(desc_msg, ret);\
    const Reflection * reflection = msg->GetReflection();\
    CHECKPTR_NULL_RETURN(reflection, ret);

#define PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, ret)\
    using namespace google::protobuf;\
    using namespace google::protobuf::compiler;\
    CHECKPTR_NULL_RETURN(msg, ret);\
    const DescriptorPool * descriptor_pool = importer_->pool();\
    CHECKPTR_NULL_RETURN(descriptor_pool, ret);\
    const EnumDescriptor *enum_desc = descriptor_pool->FindEnumTypeByName(enum_name);\
    CHECKPTR_NULL_RETURN(enum_desc, ret);\
    const Descriptor *desc_msg = descriptor_pool->FindMessageTypeByName(msg->GetTypeName());\
    CHECKPTR_NULL_RETURN(desc_msg, ret);\
    const Reflection * reflection = msg->GetReflection();\
    CHECKPTR_NULL_RETURN(reflection, ret);

protobuf_parser::protobuf_parser()
{
    using namespace google::protobuf;
    using namespace google::protobuf::compiler;
    source_tree_.reset(new DiskSourceTree);
    error_printer_.reset(new error_printer(source_tree_.get()));
    importer_.reset(new Importer(source_tree_.get(), error_printer_.get()));
    dynamic_message_factory_.reset(new DynamicMessageFactory());
}

void protobuf_parser::add_path(const std::string & proto_path)
{
    source_tree_->MapPath("", proto_path);
}

bool protobuf_parser::parse_proto(const std::string & proto_file_name)
{
    using namespace google::protobuf;
    using namespace google::protobuf::compiler;
    const FileDescriptor *file_descriptor = importer_->Import(proto_file_name);
    CHECKPTR_NULL_RETURN(file_descriptor, false);
    const DescriptorPool * descriptor_pool = importer_->pool();
    CHECKPTR_NULL_RETURN(descriptor_pool, false);
    return true;
}

bool protobuf_parser::has_field(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->HasField(*msg, field_desc);
}

bool protobuf_parser::has_field(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->HasField(*msg, field_desc);
}

int32_t protobuf_parser::field_size(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->FieldSize(*msg, field_desc);
}

int32_t protobuf_parser::field_size(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->FieldSize(*msg, field_desc);
}

bool protobuf_parser::clear_field(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->ClearField(msg, field_desc);
    return true;
}

bool protobuf_parser::clear_field(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->ClearField(msg, field_desc);
    return true;
}

google::protobuf::Message * protobuf_parser::create_msg(const std::string & msg_name) const
{
    using namespace google::protobuf;
    using namespace google::protobuf::compiler;

    const DescriptorPool * descriptor_pool = importer_->pool();
    CHECKPTR_NULL_RETURN(descriptor_pool, nullptr);

    const Descriptor *desc_msg = descriptor_pool->FindMessageTypeByName(msg_name);
    CHECKPTR_NULL_RETURN(desc_msg, nullptr);

    const Message *msg_type = dynamic_message_factory_->GetPrototype(desc_msg);
    CHECKPTR_NULL_RETURN(msg_type, nullptr);

    Message *msg = msg_type->New();
    CHECKPTR_NULL_RETURN(msg, nullptr);

    return msg;
}

google::protobuf::Message * protobuf_parser::mutable_msg(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->MutableMessage(msg, field_desc, dynamic_message_factory_.get());
}

google::protobuf::Message * protobuf_parser::mutable_msg(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->MutableMessage(msg, field_desc, dynamic_message_factory_.get());
}

google::protobuf::Message * protobuf_parser::mutable_repeated_msg(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->MutableRepeatedMessage(msg, field_desc, index);
}

google::protobuf::Message * protobuf_parser::mutable_repeated_msg(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->MutableRepeatedMessage(msg, field_desc, index);
}

const google::protobuf::Message * protobuf_parser::get_repeated_msg(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return &reflection->GetRepeatedMessage(*msg, field_desc, index);
}

const google::protobuf::Message * protobuf_parser::get_repeated_msg(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return &reflection->GetRepeatedMessage(*msg, field_desc, index);
}

bool protobuf_parser::set_msg(google::protobuf::Message * msg, google::protobuf::Message * sub_msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetAllocatedMessage(msg, sub_msg, field_desc);
    return true;
}

bool protobuf_parser::set_msg(google::protobuf::Message * msg, google::protobuf::Message * sub_msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetAllocatedMessage(msg, sub_msg, field_desc);
    return true;
}

google::protobuf::Message * protobuf_parser::add_msg(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->AddMessage(msg, field_desc, dynamic_message_factory_.get());
}

google::protobuf::Message * protobuf_parser::add_msg(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, nullptr);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, nullptr);
    return reflection->AddMessage(msg, field_desc, dynamic_message_factory_.get());
}

bool protobuf_parser::add_msg(google::protobuf::Message * msg, const std::string & field_name, google::protobuf::Message * sub_msg) const
{
    CHECKPTR_NULL_RETURN(sub_msg, false);
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddAllocatedMessage(msg, field_desc, sub_msg);
    return true;
}

bool protobuf_parser::add_msg(google::protobuf::Message * msg, const int32_t field_id, google::protobuf::Message * sub_msg) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddAllocatedMessage(msg, field_desc, sub_msg);
    return true;
}

bool protobuf_parser::set_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_repeated_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const int32_t index, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetRepeatedEnum(msg, field_desc, index, enum_value_desc);
    return true;
}

bool protobuf_parser::add_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->AddEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_repeated_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const int32_t index, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetRepeatedEnum(msg, field_desc, index, enum_value_desc);
    return true;
}

bool protobuf_parser::add_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const std::string & val_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByName(val_name);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->AddEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_repeated_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const int32_t index, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetRepeatedEnum(msg, field_desc, index, enum_value_desc);
    return true;
}

bool protobuf_parser::add_enum(google::protobuf::Message * msg, const std::string & field_name, const std::string & enum_name, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->AddEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetEnum(msg, field_desc, enum_value_desc);
    return true;
}

bool protobuf_parser::set_repeated_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const int32_t index, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->SetRepeatedEnum(msg, field_desc, index, enum_value_desc);
    return true;
}

bool protobuf_parser::add_enum(google::protobuf::Message * msg, const int32_t field_id, const std::string & enum_name, const int32_t val_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_ENUM_FIELD(msg, enum_name, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    const EnumValueDescriptor * enum_value_desc = enum_desc->FindValueByNumber(val_id);
    CHECKPTR_NULL_RETURN(enum_value_desc, false);
    reflection->AddEnum(msg, field_desc, enum_value_desc);
    return true;
}

int32_t protobuf_parser::get_enum_number(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, -1);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, -1);
    const EnumValueDescriptor* enum_desc = reflection->GetEnum(*msg, field_desc);
    CHECKPTR_NULL_RETURN(enum_desc, -1);
    return enum_desc->number();
}

int32_t protobuf_parser::get_repeated_enum_number(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, -1);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, -1);
    const EnumValueDescriptor* enum_desc = reflection->GetRepeatedEnum(*msg, field_desc, index);
    CHECKPTR_NULL_RETURN(enum_desc, -1);
    return enum_desc->number();
}

int32_t protobuf_parser::get_enum_number(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, -1);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, -1);
    const EnumValueDescriptor* enum_desc = reflection->GetEnum(*msg, field_desc);
    CHECKPTR_NULL_RETURN(enum_desc, -1);
    return enum_desc->number();
}

int32_t protobuf_parser::get_repeated_enum_number(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, -1);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, -1);
    const EnumValueDescriptor* enum_desc = reflection->GetRepeatedEnum(*msg, field_desc, index);
    CHECKPTR_NULL_RETURN(enum_desc, -1);
    return enum_desc->number();
}

std::string protobuf_parser::get_enum_name(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, "");
    const EnumValueDescriptor* enum_desc = reflection->GetEnum(*msg, field_desc);
    CHECKPTR_NULL_RETURN(enum_desc, "");
    return enum_desc->name();
}

std::string protobuf_parser::get_repeated_enum_name(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, "");
    const EnumValueDescriptor* enum_desc = reflection->GetRepeatedEnum(*msg, field_desc, index);
    CHECKPTR_NULL_RETURN(enum_desc, "");
    return enum_desc->name();
}

std::string protobuf_parser::get_repeated_enum_name(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, "");
    const EnumValueDescriptor* enum_desc = reflection->GetRepeatedEnum(*msg, field_desc, index);
    CHECKPTR_NULL_RETURN(enum_desc, "");
    return enum_desc->name();
}

std::string protobuf_parser::get_enum_name(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, "");
    const EnumValueDescriptor* enum_desc = reflection->GetEnum(*msg, field_desc);
    CHECKPTR_NULL_RETURN(enum_desc, "");
    return enum_desc->name();
}

bool protobuf_parser::set_string(google::protobuf::Message * msg, const std::string & field_name, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetString(msg, field_desc, str_val);
    return true;
}

std::string protobuf_parser::get_string(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, "");
    return reflection->GetString(*msg, field_desc);
}

bool protobuf_parser::set_repeated_string(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedString(msg, field_desc, index, str_val);
    return true;
}

std::string protobuf_parser::get_repeated_string(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, "");
    return reflection->GetRepeatedString(*msg, field_desc, index);
}

bool protobuf_parser::add_string(google::protobuf::Message * msg, const std::string & field_name, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddString(msg, field_desc, str_val);
    return true;
}

bool protobuf_parser::set_string(google::protobuf::Message * msg, const int32_t field_id, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetString(msg, field_desc, str_val);
    return true;
}

std::string protobuf_parser::get_string(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, "");
    return reflection->GetString(*msg, field_desc);
}

bool protobuf_parser::set_repeated_string(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedString(msg, field_desc, index, str_val);
    return true;
}

std::string protobuf_parser::get_repeated_string(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, "");
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, "");
    return reflection->GetRepeatedString(*msg, field_desc, index);
}


bool protobuf_parser::add_string(google::protobuf::Message * msg, const int32_t field_id, const std::string & str_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddString(msg, field_desc, str_val);
    return true;
}

bool protobuf_parser::set_float(google::protobuf::Message * msg, const std::string & field_name, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetFloat(msg, field_desc, float_val);
    return true;
}

float protobuf_parser::get_float(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0.0f);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0.0f);
    return reflection->GetFloat(*msg, field_desc);
}

bool protobuf_parser::set_repeated_float(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedFloat(msg, field_desc, index, float_val);
    return true;
}

float protobuf_parser::get_repeated_float(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0.0f);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0.0f);
    return reflection->GetRepeatedFloat(*msg, field_desc, index);
}

bool protobuf_parser::add_float(google::protobuf::Message * msg, const std::string & field_name, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddFloat(msg, field_desc, float_val);
    return true;
}

bool protobuf_parser::set_float(google::protobuf::Message * msg, const int32_t field_id, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetFloat(msg, field_desc, float_val);
    return true;
}

float protobuf_parser::get_float(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0.0f);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0.0f);
    return reflection->GetFloat(*msg, field_desc);
}

bool protobuf_parser::set_repeated_float(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedFloat(msg, field_desc, index, float_val);
    return true;
}

float protobuf_parser::get_repeated_float(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0.0f);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0.0f);
    return reflection->GetRepeatedFloat(*msg, field_desc, index);
}

bool protobuf_parser::add_float(google::protobuf::Message * msg, const int32_t field_id, const float float_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddFloat(msg, field_desc, float_val);
    return true;
}

bool protobuf_parser::set_double(google::protobuf::Message * msg, const std::string & field_name, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetDouble(msg, field_desc, double_val);
    return true;
}

double protobuf_parser::get_double(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetDouble(*msg, field_desc);
}

bool protobuf_parser::set_repeated_double(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedDouble(msg, field_desc, index, double_val);
    return true;
}

double protobuf_parser::get_repeated_double(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedDouble(*msg, field_desc, index);
}

bool protobuf_parser::add_double(google::protobuf::Message * msg, const std::string & field_name, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddDouble(msg, field_desc, double_val);
    return true;
}

bool protobuf_parser::set_double(google::protobuf::Message * msg, const int32_t field_id, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetDouble(msg, field_desc, double_val);
    return true;
}

double protobuf_parser::get_double(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetDouble(*msg, field_desc);
}

bool protobuf_parser::set_repeated_double(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedDouble(msg, field_desc, index, double_val);
    return true;
}

double protobuf_parser::get_repeated_double(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedDouble(*msg, field_desc, index);
}

bool protobuf_parser::add_double(google::protobuf::Message * msg, const int32_t field_id, const double double_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddDouble(msg, field_desc, double_val);
    return true;
}

bool protobuf_parser::set_int32(google::protobuf::Message * msg, const std::string & field_name, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetInt32(msg, field_desc, int32_val);
    return true;
}

int32_t protobuf_parser::get_int32(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetInt32(*msg, field_desc);
}

bool protobuf_parser::set_repeated_int32(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedInt32(msg, field_desc, index, int32_val);
    return 0;
}

int32_t protobuf_parser::get_repeated_int32(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedInt32(*msg, field_desc, index);
}

bool protobuf_parser::add_int32(google::protobuf::Message * msg, const std::string & field_name, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddInt32(msg, field_desc, int32_val);
    return 0;
}

bool protobuf_parser::set_int32(google::protobuf::Message * msg, const int32_t field_id, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetInt32(msg, field_desc, int32_val);
    return true;
}

int32_t protobuf_parser::get_int32(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetInt32(*msg, field_desc);
}

bool protobuf_parser::set_repeated_int32(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedInt32(msg, field_desc, index, int32_val);
    return true;
}

int32_t protobuf_parser::get_repeated_int32(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedInt32(*msg, field_desc, index);
}

bool protobuf_parser::add_int32(google::protobuf::Message * msg, const int32_t field_id, const int32_t int32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddInt32(msg, field_desc, int32_val);
    return true;
}

bool protobuf_parser::set_uint32(google::protobuf::Message * msg, const std::string & field_name, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetUInt32(msg, field_desc, uint32_val);
    return true;
}

uint32_t protobuf_parser::get_uint32(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetUInt32(*msg, field_desc);
}

bool protobuf_parser::set_repeated_uint32(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedUInt32(msg, field_desc, index, uint32_val);
    return true;
}

uint32_t protobuf_parser::get_repeated_uint32(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedUInt32(*msg, field_desc, index);
}

bool protobuf_parser::add_uint32(google::protobuf::Message * msg, const std::string & field_name, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddUInt32(msg, field_desc, uint32_val);
    return true;
}

bool protobuf_parser::set_uint32(google::protobuf::Message * msg, const int32_t field_id, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetUInt32(msg, field_desc, uint32_val);
    return true;
}

uint32_t protobuf_parser::get_uint32(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetUInt32(*msg, field_desc);
}

bool protobuf_parser::set_repeated_uint32(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedUInt32(msg, field_desc, index, uint32_val);
    return true;
}

uint32_t protobuf_parser::get_repeated_uint32(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedUInt32(*msg, field_desc, index);
}

bool protobuf_parser::add_uint32(google::protobuf::Message * msg, const int32_t field_id, const uint32_t uint32_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddUInt32(msg, field_desc, uint32_val);
    return true;
}

bool protobuf_parser::set_int64(google::protobuf::Message * msg, const std::string & field_name, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetInt64(msg, field_desc, int64_val);
    return true;
}

int64_t protobuf_parser::get_int64(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetInt64(*msg, field_desc);
}

bool protobuf_parser::set_repeated_int64(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedInt64(msg, field_desc, index, int64_val);
    return true;
}

int64_t protobuf_parser::get_repeated_int64(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedInt64(*msg, field_desc, index);
}

bool protobuf_parser::add_int64(google::protobuf::Message * msg, const std::string & field_name, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddInt64(msg, field_desc, int64_val);
    return true;
}

bool protobuf_parser::set_int64(google::protobuf::Message * msg, const int32_t field_id, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetInt64(msg, field_desc, int64_val);
    return true;
}

int64_t protobuf_parser::get_int64(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetInt64(*msg, field_desc);
}

bool protobuf_parser::set_repeated_int64(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedInt64(msg, field_desc, index, int64_val);
    return true;
}

int64_t protobuf_parser::get_repeated_int64(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedInt64(*msg, field_desc, index);
}

bool protobuf_parser::add_int64(google::protobuf::Message * msg, const int32_t field_id, const int64_t int64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddInt64(msg, field_desc, int64_val);
    return true;
}

bool protobuf_parser::set_uint64(google::protobuf::Message * msg, const std::string & field_name, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetUInt64(msg, field_desc, uint64_val);
    return true;
}

uint64_t protobuf_parser::get_uint64(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetUInt64(*msg, field_desc);
}

bool protobuf_parser::set_repeated_uint64(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedUInt64(msg, field_desc, index, uint64_val);
    return true;
}

uint64_t protobuf_parser::get_repeated_uint64(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedUInt64(*msg, field_desc, index);
}

bool protobuf_parser::add_uint64(google::protobuf::Message * msg, const std::string & field_name, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddUInt64(msg, field_desc, uint64_val);
    return true;
}

bool protobuf_parser::set_uint64(google::protobuf::Message * msg, const int32_t field_id, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetUInt64(msg, field_desc, uint64_val);
    return true;
}

uint64_t protobuf_parser::get_uint64(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetUInt64(*msg, field_desc);
}

bool protobuf_parser::set_repeated_uint64(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedUInt64(msg, field_desc, index, uint64_val);
    return true;
}

uint64_t protobuf_parser::get_repeated_uint64(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, 0);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, 0);
    return reflection->GetRepeatedUInt64(*msg, field_desc, index);
}

bool protobuf_parser::add_uint64(google::protobuf::Message * msg, const int32_t field_id, const uint64_t uint64_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddUInt64(msg, field_desc, uint64_val);
    return true;
}

bool protobuf_parser::set_bool(google::protobuf::Message * msg, const std::string & field_name, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetBool(msg, field_desc, bool_val);
    return true;
}

bool protobuf_parser::get_bool(google::protobuf::Message * msg, const std::string & field_name) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->GetBool(*msg, field_desc);
}

bool protobuf_parser::set_repeated_bool(google::protobuf::Message * msg, const std::string & field_name, const int32_t index, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedBool(msg, field_desc, index, bool_val);
    return true;
}

bool protobuf_parser::get_repeated_bool(google::protobuf::Message * msg, const std::string & field_name, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->GetRepeatedBool(*msg, field_desc, index);
}

bool protobuf_parser::add_bool(google::protobuf::Message * msg, const std::string & field_name, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByName(field_name);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddBool(msg, field_desc, bool_val);
    return true;
}

bool protobuf_parser::set_bool(google::protobuf::Message * msg, const int32_t field_id, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetBool(msg, field_desc, bool_val);
    return true;
}

bool protobuf_parser::get_bool(google::protobuf::Message * msg, const int32_t field_id) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->GetBool(*msg, field_desc);
}

bool protobuf_parser::set_repeated_bool(google::protobuf::Message * msg, const int32_t field_id, const int32_t index, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->SetRepeatedBool(msg, field_desc, index, bool_val);
    return true;
}

bool protobuf_parser::get_repeated_bool(google::protobuf::Message * msg, const int32_t field_id, const int32_t index) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    return reflection->GetRepeatedBool(*msg, field_desc, index);
}

bool protobuf_parser::add_bool(google::protobuf::Message * msg, const int32_t field_id, const bool bool_val) const
{
    PRAPARE_DESCRIPTOR_AND_REFLECTION_FOR_SIMPLE_FIELD(msg, false);
    const FieldDescriptor * field_desc = desc_msg->FindFieldByNumber(field_id);
    CHECKPTR_NULL_RETURN(field_desc, false);
    reflection->AddBool(msg, field_desc, bool_val);
    return true;
}
